#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../src/bscpoll.h"

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <WinSock2.h>
#include <Windows.h>
#endif


char *host = "192.168.1.10", *port = "11300", errorstr[BSC_ERRSTR_LEN];
static bsc_error_t bsc_error;
static int reconnect_attempts = 5, finished = 0;
uint64_t reserve_id;
char* reserve_str = NULL;
int reserve_len = 0;

void reply_cb(bsc *client, struct bsc_reply_info * info) {
	finished = true;
}

void reserve_cb(bsc *client, struct bsc_reserve_info *info)
{
	//printf("got reserve %llu %s\n", info->response.id,(const char*)info->response.data);
	if (info->response.code == BSC_RESERVE_RES_RESERVED) {
		reserve_str = realloc(reserve_str, info->response.bytes + 1);
		reserve_len = info->response.bytes + 1;
		strncpy(reserve_str, info->response.data, info->response.bytes);
		reserve_id = info->response.id;
	}
	else {
		reserve_id = 0;
	}
	finished = true;
}


static void reconnect(bsc *client, bsc_error_t error)
{
	char errorstr[BSC_ERRSTR_LEN];

	switch (error) {
	case BSC_ERROR_INTERNAL:
		fprintf(stderr, "critical error: recieved BSC_ERROR_INTERNAL, quitting\n");
		break;
	case BSC_ERROR_MEMORY:
		fprintf(stderr, "critical error: recieved BSC_ERROR_MEMORY, quitting\n");
		break;
	case BSC_ERROR_SOCKET:
		fprintf(stderr, "error: recieved BSC_ERROR_SOCKET, attempting to reconnect ...\n");
		--reconnect_attempts;
		bsc_connect_async(client, errorstr);
		fprintf(stderr, "error: reconnect attempt %d ", reconnect_attempts);
		break;
	default:
		fprintf(stderr, "critical error: got unknown error (%d)\n", error);
	}

	if (reconnect_attempts == 0)
		exit(EXIT_FAILURE);
}


#define WAIT_FINISH \
	finished = false; \
	while (!finished) {\
		if (bscpoll_wait(poll,5000) == EXIT_FAILURE)\
			return EXIT_FAILURE;\
	}\


void put_cb(bsc *client, struct bsc_put_info *info)
{
	if (info->response.code == BSC_PUT_RES_INSERTED) {
		printf("put cb %llu\n", info->response.id);
	}
	else {
		printf("put error %d\n", info->response.code);
	}

	finished = true;
}



int main(int argc, char **argv)
{
	int i;
	bsc_poll* poll;
	bsc *client;

#ifdef _WIN32
	WSADATA ws;
	WSAStartup(MAKEWORD(2, 2), &ws);
#endif

	poll = create_bscpoll();

	client = bsc_new(host, port, "default", reconnect, 16, 12, 4, errorstr);
	if (!client) {
		fprintf(stderr, "bsc_new: %s", errorstr);
		return EXIT_FAILURE;
	}

	bscpoll_add(poll, client);

	uint32_t time = GetTickCount();
	const char* test = "MXErsI9x97SnMeeebshgSY3vmV2u7MQ9eZE6nJnCkTiZclhcT6WlKmLeuaujPSW34naC5k8nIPJvt0yzDpgcv7BubRYo3vN44Zfk";

	for (i = 0; i<10000; ++i)
	{
		bsc_error = bsc_put(client, put_cb, NULL, 1024, 5, 3, strlen(test) + 1, test, false);
		if (bsc_error != BSC_ERROR_NONE)
			fprintf(stderr, "bsc_call failed (%d)", bsc_error);

		WAIT_FINISH;
	}

	printf("cost %d ms\n", GetTickCount() - time);

	bsc_free(client);
	destroy_bscpoll(poll);
	free(reserve_str);
}
